package com.nextbusmn.server.JDOWrappers;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import com.google.appengine.api.datastore.Key;
import com.nextbusmn.server.dataobjects.CalendarDateData;
import com.nextbusmn.server.dataobjects.NextBusData;
import com.nextbusmn.server.dataobjects.StopTimeData;

public class StopTimeJDOWrapper extends JDOWrapper {
	
	public StopTimeJDOWrapper(StopTimeData data) {
		this.setData(data);
	}
	
	@Override
	public boolean dataExists(NextBusData data) {
		
		// use key???
		StopTimeData id = getByTripIDAndStopID(((StopTimeData) data).getTripID(),
				((StopTimeData) data).getStopID());
		return id != null;
	}

	public static StopTimeData getByTripIDAndStopID(String tid, int sid) {
		PersistenceManager pm = getPersistenceManagerFactory().getPersistenceManager();
		
		Query query = pm.newQuery(StopTimeData.class);
		query.setFilter("tripID == tIDParam && stopID == sIDParam");
		query.declareParameters("String tIDParam, String sIDParam");

		List<StopTimeData> result = null;
		
		try {
			result = (List<StopTimeData>) query.execute(tid, sid);
		} finally {
			query.closeAll();
		}
		
		if (result.size() > 1) {
			System.out.println("Data problem: Key not unique!"); 
		}
		
		return result.size() == 1 ? result.get(0) : null;
	}
	
	public static List<StopTimeData> getStopTimesByTripID(String tripID) {
		PersistenceManager pm = getPersistenceManagerFactory().getPersistenceManager();
		
		
		Query query = pm.newQuery(StopTimeData.class);
		
		// TODO detach code here
			query.setFilter("tripID == paramID");
			query.declareParameters("String paramID");
			
			List<StopTimeData> result = null;
			
			try {
				result = (List<StopTimeData>) query.execute(tripID);
			} finally {
				query.closeAll();
			}
			
			
		
		
		return result;
	}
	
	public static List<StopTimeData> getByStopID(int stopID) {
		PersistenceManager pm = getPersistenceManagerFactory().getPersistenceManager();
		
		Query query = pm.newQuery(StopTimeData.class);
		
		query.setFilter("stopID == paramID");
		query.declareParameters("String paramID");
		
		List<StopTimeData> result = null;
		List<StopTimeData> detached = null;
		
		
		try {
			result = (List<StopTimeData>) query.execute(stopID);
			detached = (List<StopTimeData>) pm.detachCopyAll(result);
		} finally {
			query.closeAll();
		}
		
		return detached;
	}
	
	public static void update(StopTimeData std) {
		PersistenceManager pm = getPersistenceManagerFactory().getPersistenceManager();
		try {
            pm.makePersistent(std);
        } finally {
            pm.close();
        }

	}
	
	public static List<StopTimeData> getStopTimesByTripIDs(List<String> tripIDs) {
        PersistenceManager pm = getPersistenceManagerFactory().getPersistenceManager();
        
        List<StopTimeData> finalList = new ArrayList<StopTimeData>();
        
        Query query = pm.newQuery(StopTimeData.class);
        
        for (String tID : tripIDs) {
                query.setFilter("tripID == paramID");
                query.declareParameters("String paramID");
                
                List<StopTimeData> result = null;
                
                try {
                        result = (List<StopTimeData>) query.execute(tID);
                } finally {
                        query.closeAll();
                }
                
                finalList.addAll(result);
        }
        
        return finalList;
}

	@SuppressWarnings("deprecation") // Google's datastore can't persist Calendar objects
	public static List<StopTimeData> getNextTrips(int sid, int numberToReturn, Calendar startTime) {
		PersistenceManager pm = getPersistenceManagerFactory().getPersistenceManager();
		
		Date day = new Date(startTime.get(Calendar.YEAR), startTime.get(Calendar.MONTH), 
				startTime.get(Calendar.DATE));
		
		//Date time = new Date(0, 0, 1, startTime.get(Calendar.HOUR), startTime.get(Calendar.MINUTE));
		
		Query queryDate = pm.newQuery(CalendarDateData.class);
		queryDate.setFilter("date == dateParam && exceptionType == 1");
		queryDate.declareParameters("java.util.Date dateParam");
		
		List<CalendarDateData> dateData = (List<CalendarDateData>) queryDate.execute(day);
		
		int serviceType;
		
		if (dateData.size() > 0) {
			if (dateData.get(0).getServiceID().indexOf("Holiday") != -1) {
				serviceType = 3;
			} else
			if (dateData.get(0).getServiceID().indexOf("Sunday") != -1) {
				serviceType = 2;
			} else
			if (dateData.get(0).getServiceID().indexOf("Saturday") != -1) {
				serviceType = 1; 
			} else {
				serviceType = 0;
			}
			
		} else {
			if (startTime.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
				serviceType = 1;
			} else 
			if (startTime.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
				serviceType = 2;
			} else {
				serviceType = 0;
			}
		}
		
		Query query = pm.newQuery(StopTimeData.class);
		query.setOrdering("departureTime asc");
		query.setFilter("stopID == sIDParam " + 
				"&& serviceType == stParam");
		query.declareParameters("int sIDParam, int stParam");
		
		
		List<StopTimeData> data = new ArrayList<StopTimeData>();
		try {
			data = (List<StopTimeData>) query.execute(sid, serviceType);
		} finally {
            query.closeAll();
		}
		
		return data;
	}
	
	public static List<StopTimeData> getAllRows() {
		return (List<StopTimeData>) JDOWrapper.getAllRows(StopTimeData.class);
	}
	
	public static List<StopTimeData> getBusStopTimesByParentId(Key user_key) {
		PersistenceManager pm = getPersistenceManagerFactory().getPersistenceManager();  
		
		Query query = pm.newQuery(StopTimeData.class);
		query.setFilter("key == keyParam");
		query.declareParameters("String keyParam");
		
//	    Query query = pm.newQuery("select from "+StopTimeData.class.getName()+" WHERE trip == keyParam");
//	    query.declareParameters("String keyParam");
	   // query.setUnique(true);
	    List<StopTimeData> theData = (List<StopTimeData>) query.execute(user_key.getId());
	    System.out.println(theData.size());
	    return theData;
	}

	public static List<StopTimeData> getByRouteKey(Key key) {
		PersistenceManager pm = getPersistenceManagerFactory().getPersistenceManager();
		
		List<StopTimeData> finalList = new ArrayList<StopTimeData>();
		
		Query query = pm.newQuery("select from " + StopTimeData.class.getName() +
				" where trip.busRoute == routeKey"); 
	    query.setOrdering("stopSequence asc");
	    query.declareParameters("String routeKey");
	    
	    try {
	    	finalList = (List<StopTimeData>) query.execute(key);
	    } finally {
	    	query.closeAll();
	    }
		return finalList;
	}

	public static List<StopTimeData> getAllTripsByService(int sid,
			String serviceTypes) {
		PersistenceManager pm = getPersistenceManagerFactory().getPersistenceManager();
		
		StringBuilder filterString = new StringBuilder("stopID == sIDParam && (");
		if (serviceTypes.indexOf('w') != -1) {
			filterString.append(" serviceType == 0 || ");
		}
		if (serviceTypes.indexOf('a') != -1) {
			filterString.append(" serviceType == 1 || ");
		}
		if (serviceTypes.indexOf('u') != -1) {
			filterString.append(" serviceType == 2 || ");
		}
		if (serviceTypes.indexOf('h') != -1) {
			filterString.append(" serviceType == 3 || ");
		}
		String finalFilter = filterString.substring(0, filterString.lastIndexOf("||")) + ")";
		
		System.out.println(finalFilter);
		
		Query query = pm.newQuery(StopTimeData.class);
		query.setFilter(finalFilter); 
		query.declareParameters("int sIDParam");
		
		List<StopTimeData> data = new ArrayList<StopTimeData>();
		try {
			data = (List<StopTimeData>) query.execute(sid);
		} finally {
            query.closeAll();
		}
		
		return data;
	}
}
